import {AnyAction, Reducer} from 'redux';
import {EffectsCommandMap} from 'dva';
import {fetchChatRecords} from './service';
import {mapChatRecords} from './data';

export type Effect = (
  action: AnyAction,
  effects: EffectsCommandMap & { select: <T>(func: (state: {}) => T) => T },
) => void;

export interface ModelState {
  roomList: any[];
  userList: any[];

  roomBadge: Record<string, number>;
  userBadge: Record<string, number>;

  roomRecords: mapChatRecords;
  secretRecords: mapChatRecords;
}

export interface ModelType {
  namespace: string;
  state: ModelState;
  effects: {
    fetchRecords: Effect;
    saveRoomRecords: Effect;
    saveSecretRecords: Effect;
  };
  reducers: {
    save: Reducer<{}>;
    initChatRecords: Reducer<{}>;
    userOnOffLine: Reducer<{}>;
    pushRoomRecords: Reducer<{ roomRecords: mapChatRecords }>;
    pushSecretRecords: Reducer<{ secretRecords: mapChatRecords }>;
    saveUserBadge: Reducer<{}>;
    saveRoomBadge: Reducer<{}>;
  };
}

const Model: ModelType = {
  namespace: 'chatIM',

  state: {
    roomList: [],
    userList: [],
    roomBadge: {},
    userBadge: {},
    roomRecords: {},
    secretRecords: {},
  },

  effects: {
    * fetchRecords({payload}, {call, put}) {
      const response = yield call(fetchChatRecords, payload);
      yield put({
        type: 'initChatRecords',
        payload: response.data,
      });
    },

    * saveRoomRecords({payload, badge}, {put}) {
      const putList = [
        put({
          type: 'pushRoomRecords',
          payload: payload
        })
      ];
      badge && putList.push(
        put({
          type: 'saveRoomBadge',
          payload: badge
        })
      );
      yield putList
    },
    * saveSecretRecords({payload, badge}, {put}) {
      const putList = [put({
        type: 'pushSecretRecords',
        payload: payload
      })];
      badge && putList.push(put({
        type: 'saveUserBadge',
        payload: badge
      }));
      yield putList;
    },
  },

  reducers: {
    save(state, action) {
      return {
        ...state,
        data: action.payload,
      };
    },
    initChatRecords(state, action) {
      return {
        ...state,
        roomRecords: action.payload.groupRecords,
        secretRecords: action.payload.secretRecords,
        userList: action.payload.userList,
        roomList: action.payload.roomList,
      };
    },
    userOnOffLine(state, action) {
      return {
        ...state,
        userList: action.payload,
      };
    },
    pushRoomRecords(state, action) {
      return {
        ...state,
        roomRecords: action.payload,
      };
    },
    pushSecretRecords(state, action) {
      return {
        ...state,
        secretRecords: action.payload,
      };
    },
    saveUserBadge(state, action) {
      return {
        ...state,
        userBadge: action.payload,
      };
    },
    saveRoomBadge(state, action) {
      return {
        ...state,
        roomBadge: action.payload,
      };
    },
  }
};

export default Model;
